/**
 * 
 */
package org.stars.database.connectionpool;

import java.sql.Connection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.stars.database.ConnectionPoolManager;
import org.stars.database.diagnostic.TraceableConnectionWrapper;
import org.stars.util.StringGenerator;
import org.stars.util.diagnostic.StackTraceDiagnosticHandler;
import org.stars.util.diagnostic.StackTraceDiagnosticHelper;

/**
 * Classe di base per tutti connection pool. Tutte le informazioni ed i metodi
 * in comune vengono messi qua.
 * 
 * @author Francesco Benincasa (908099)
 * 
 */
public abstract class ConnectionPoolBase {
	
	protected static Log getLogger()
	{
		return LogFactory.getLog(ConnectionPoolBase.class);
	}	

	protected Map<String, List<String>> openedConnections;

	/**
	 * 
	 */
	protected boolean traceable;

	/**
	 * @return
	 */
	public boolean isTraceable() {
		return traceable;
	}

	/**
	 * @param value
	 */
	public void setTraceable(boolean value) {
		traceable = value;
	}

	protected String info;

	/**
	 * @return the info
	 */
	public String getInfo() {
		return info;
	}

	/**
	 * @param info
	 *            the info to set
	 */
	public void setInfo(String info) {
		this.info = info;
	}

	/**
	 * costruttore
	 */
	public ConnectionPoolBase() {
		pg = new StringGenerator(8);
		openedConnections = new HashMap<String, List<String>>();
	}

	protected StringGenerator pg;
	
	/**
	 * Return a string with date and time 
	 * 
	 * @return
	 */
	protected static String getDateAndTimeString()
	{
		Date today=new Date();
		return ((Long)(today.getTime())).toString();			
	}
	

	/**
	 * Restituisce una connessione. Nel caso in cui traceable sia impostato a
	 * true, viene incapsulata nell'apposito wrapper
	 * 
	 * @param connection
	 * @return
	 */
	public Connection getConnection(Connection connection) {
		if (traceable) {
			StackTraceDiagnosticHandler handler = ConnectionPoolManager.getInstance().getStackTraceDiagnosticHandler();

			// generiamo il token
			String key = getDateAndTimeString() + "-" + pg.generate();

			List<String> startUse = StackTraceDiagnosticHelper.getStackInfoList(handler);

			registryConnection(key, startUse);
			return new TraceableConnectionWrapper(this, key, connection);
		}

		return connection;
	}

	public void registryConnection(String key, List<String> start) {
		openedConnections.put(key, start);
	}

	public void unregistryConnection(String key) {
		if (openedConnections.containsKey(key)) {
			openedConnections.remove(key);
		}

	}

	/**
	 * Indica se ci sono connessioni aperte
	 * 
	 * @return
	 */
	public boolean hasOpenedConnections() {
		return openedConnections.size() == 0 ? false : true;
	}

	public Map<String, List<String>> getOpenedConnectionDetails() {
		return openedConnections;
	}

}
